﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using Core.DataAccess;
using Core.DataAccess.IRepositories;
using Core.DataAccess.Repositories;
using Core.Common;
using Core.BusinessLogic.Interfaces;
using Core.Interfaces;
using System.Web;

namespace Core.BusinessLogic
{
    [Export(typeof(IAccountService))]
    public class AccountService : IAccountService
    {
        [Import]
        private IAccountRepository _accountRepository;
        [Import]
        private IPermissionRepository _permissionRepository;
        [Import]
        private IUserProviderRepository _userproviderRepository;
        [Import]
        private IFriendRepository _friendRepository;
        [Import]
        private IUserSession _userSession;
        [Import]
        private IRedirector _redirector;
        [Import]
        private IEmail _email;
        [Import]
        private IStatusChatRepository _statusChatRepository;
        [Import]
        private ILevelRepository _levelRepository;

        public AccountService()
        {
            MEFManager.Compose(this);
        }

        public bool UsernameInUse(string Username)
        {
            Account account = _accountRepository.GetAccountByUsername(Username);
            if (account != null)
                return true;

            return false;
        }

        public bool EmailInUse(string Email)
        {
            Account account = _accountRepository.GetAccountByEmail(Email);
            if (account != null)
                return true;

            return false;
        }

        public void Logout()
        {
            _userSession.IsLogged = false;
            _userSession.CurrentUser = null;
            _userSession.UserName = "";
            //_redirector.GoToLoginPage();
        }

        public string Login(string Username, string Password)
        {
            Account account = _accountRepository.GetAccountByUsername(Username);
                   
            if (account != null)
            {
                Password = Extensions.Encrypt(Password, account.Plaintext);                                
                if (account.Password == Password)
                {
                    if (account.IsLock == false)
                    {
                        if (account.EmailVerified)
                        {
                            _userSession.IsLogged = true;
                            _userSession.UserName = Username;
                            _userSession.CurrentUser = GetAccountByID(account.AccountID);
                            
                            // Update level                            
                            if (Convert.ToInt32(account.LevelID) < _levelRepository.NumberLevel())
                            {
                                int scoreUp = _levelRepository.GetNextScoreUpByLevelID(Convert.ToInt32(account.LevelID) + 1);
                                if (scoreUp != -1 && account.Score >= scoreUp)
                                {
                                    _accountRepository.UpdateLevelAccountByAccountID(account.AccountID, Convert.ToInt32(account.LevelID) + 1);
                                    // bonus score
                                    _accountRepository.UpdateScoreAccountByAccountID(account.AccountID, Convert.ToInt32(account.Score) + 5);
                                }
                            }

                            // update status chat is true
                            _statusChatRepository.UpdateStatusChat(account.AccountID, true);

                            // Reset count login
                            _accountRepository.ResetCountLoginByUsername(Username);                            

                            _redirector.GoToProfilesProfile();
                        }
                        else
                        {
                            _email.SendEmailAddressVerificationEmail(account.Username, account.Email);
                            return "Vui lòng kích hoạt email .";
                        }
                    }
                    else
                        return "Tài khoản của bạn đã bị khóa,vui lòng liên hệ quản trị để mở khóa.";
                }
                else
                {
                    // Get Count Login
                    if (_accountRepository.GetCountLoginByUsername(Username) < 5 && account.IsLock == false)
                    {
                        _accountRepository.UpdateCountLoginByUsername(Username);
                        if (_accountRepository.GetCountLoginByUsername(Username) >= 5)
                        {
                            _accountRepository.IsLockAccount(Username, true);
                            _accountRepository.ResetCountLoginByUsername(Username);
                            return "Đăng nhập sai 5 lần,tài khoản của bạn đã bị khóa.";
                        }
                        return "Mật khẩu không đúng.Đăng nhập sai 5 lần,tài khoản của bạn sẽ bị khóa.";
                    }
                    else
                        return "Tài khoản của bạn đã bị khóa,vui lòng liên hệ quản trị để mở khóa.";
                }
            }
            return "Tên đăng nhập không tồn tại !";
        }


        public Account GetAccountByID(Int32 AccountID)
        {
            return _accountRepository.GetAccountByID(AccountID);
        }

        public Account GetAccountByEmail(string Email)
        {
            return _accountRepository.GetAccountByEmail(Email);
        }

        public Account GetAccountByUsername(string Username)
        {
            return _accountRepository.GetAccountByUsername(Username);
        }

        public void SaveAccount(Account account)
        {
            bool isNew = account.AccountID < 1;
            _accountRepository.SaveAccount(account);
            if (isNew)
            {
                _accountRepository.CreateProfileForAccount(account);
                AddFriendWhenRegister(account);
            }
        }

        private void AddFriendWhenRegister(Account account)
        {
            Friend friend = new Friend { AccountID = account.AccountID, MyFriendsAccountID = account.AccountID, CreateDate = DateTime.Now };
            _friendRepository.AddFriendByAccountID(friend);
        }

        public List<Account> GetAllAccounts(Int32 PageNumber, Int32 pageSize)
        {
            return _accountRepository.GetAllAccounts(PageNumber, pageSize);
        }

        public void AddPermission(Account account, Permission permission)
        {
            _accountRepository.AddPermission(account, permission);
        }

        public Account RegisterWithFacebookAccount(FacebookAccount fa)
        {
            Account account = new Account();
            account.Username = "FB_" + fa.username;
            //account.Email = fa.email;
            account.BirthDate = Convert.ToDateTime(fa.birthday);
            account.CreateDate = DateTime.Now;
            account.EmailVerified = true;
            account.FirstName = fa.first_name;
            account.LastName = fa.last_name;
            account.LastUpdateDate = DateTime.Now;

            SaveAccount(account);
            account = GetAccountByUsername(account.Username);

            UserProvider up = new UserProvider();
            up.AccountID = account.AccountID;
            up.Provider = UserProviderEnum.Facebook.ToString();
            up.Auth_ID = fa.id;
            up.Auth_Username = fa.username;
            _userproviderRepository.CreateUserProvider(up);

            return account;
        }


        public void LoginWithFacebookAccount(FacebookAccount fa)
        {
            Account account = GetAccountByUsername("FB_" + fa.username);
            if (account == null) account = RegisterWithFacebookAccount(fa);

            _userSession.IsLogged = true;
            _userSession.UserName = fa.username;
            _userSession.CurrentUser = account;
            _redirector.GoToProfilesProfile();
        }

        public List<Account> GetAccountsByAccountIDList(List<int> accountIDs)
        {
            return _accountRepository.GetAccountsByAccountIDList(accountIDs);
        }

        public bool UpdatePassword(int accountID, string password)
        {            
            return _accountRepository.UpdatePassword(accountID, password);
        }

        public bool CheckPassword(string accountID, string password)
        {            
            return _accountRepository.CheckPassword(accountID, password);
        }

        public List<Account> GetRandomListAccount()
        {
            return _accountRepository.GetRandomListAccount();
        }

        public List<Account> GetListAccountsByTextSearch(string text)
        {
            return _accountRepository.GetListAccountsByTextSearch(text);
        }

        public int CheckAccountByAccountID(int accountID, int friendAccountID)
        {
            return _accountRepository.CheckAccountByAccountID(accountID, friendAccountID);
        }

        public int GetCountLoginByUsername(string username)
        {
            return _accountRepository.GetCountLoginByUsername(username);
        }

        public void UpdateCountLoginByUsername(string username)
        {
            _accountRepository.UpdateCountLoginByUsername(username);
        }

        public void ResetCountLoginByUsername(string username)
        {
            _accountRepository.ResetCountLoginByUsername(username);
        }


        public void IsLockAccount(string username, bool isLock)
        {
            _accountRepository.IsLockAccount(username, isLock);
        }

        public List<Account> GetAllAccounts()
        {
            return _accountRepository.GetAllAccounts();
        }

        public void UpdateMember_AdminPage(int accountID, int levelID, bool isLock)
        {
            _accountRepository.UpdateMember_AdminPage(accountID, levelID, isLock);
        }

        public void DeleteAccountByAccountID(int accountID)
        {
            _accountRepository.DeleteAccountByAccountID(accountID);
        }

        public void DeleteAccount(Account account)
        {
            _accountRepository.DeleteAccount(account);
        }

        public string GetPlainTextByAccountID(int accountID)
        {
            return _accountRepository.GetPlainTextByAccountID(accountID);
        }

        public int GetLevelIDByAccountID(int accountID)
        {
            return _accountRepository.GetLevelIDByAccountID(accountID);
        }

        public int GetScoreByAccountID(int accountID)
        {
            return _accountRepository.GetScoreByAccountID(accountID);
        }
    }
}
